﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using K9Nano.Authentication;
using K9Nano.Caching;
using K9Nano.Caching.EntityCaching;
using K9Nano.Dependency;
using K9Nano.MultiTenancy;
using K9Nano.Organization;

namespace K9Nano.Events.Entity
{
    public class DefaultEntityChangeReport : IEntityChangeReport, ISingletonDependency
    {
        private readonly IEventBus _eventBus;
        private readonly ITypedCacheCleanerFactory _cacheCleanerFactory;

        public DefaultEntityChangeReport(IEventBus eventBus, ITypedCacheCleanerFactory cacheCleanerFactory)
        {
            _eventBus = eventBus;
            _cacheCleanerFactory = cacheCleanerFactory;
        }

        public void Trigger(IEnumerable<EntityChange> changes)
        {
            foreach (var change in changes)
            {
                if (!change.EventDisabled)
                {
                    foreach (var eventDataType in change.EntityEventDataTypes)
                    {
                        var eventData = (IEventData)Activator.CreateInstance(eventDataType, change.Entity); // 约定的构造函数
                        _eventBus.Trigger(eventDataType, eventData, true);
                    }
                }

                if (!change.CacheDisabled)
                {
                    ClearCache(change);
                }
            }
        }

        private void ClearCache(EntityChange change)
        {
            var entityCache = _cacheCleanerFactory.Create(change.EntityType);
            var cacheKey = change.Id.ToString();
            entityCache.Remove(cacheKey);

            if (typeof(Tenant).IsAssignableFrom(change.EntityType))
            {
                var tenantCache = _cacheCleanerFactory.Create<SharedTenantCacheItem>();
                tenantCache.Remove(cacheKey);
            }
            else if (typeof(User).IsAssignableFrom(change.EntityType))
            {
                var userCache = _cacheCleanerFactory.Create<SharedUserCacheItem>();
                userCache.Remove(cacheKey);
            }
            else if (typeof(OrganizationUnit).IsAssignableFrom(change.EntityType))
            {
                var orgCache = _cacheCleanerFactory.Create<SharedOrganizationCacheItem>();
                orgCache.Remove(cacheKey);
            }
        }

        public async Task TriggerAsync(IEnumerable<EntityChange> changes)
        {
            foreach (var change in changes)
            {
                if (!change.EventDisabled)
                {
                    foreach (var eventDataType in change.EntityEventDataTypes)
                    {
                        var eventData = (IEventData)Activator.CreateInstance(eventDataType, change.Entity); // 约定的构造函数
                        await _eventBus.TriggerAsync(eventDataType, eventData, true);
                    }
                }

                if (!change.CacheDisabled)
                {
                    ClearCache(change);
                }
            }
        }
    }
}